package com.viewer.anaglyph;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;


import badLogic.MeshLoader;
import badLogic.Texture;
import badLogic.Mesh;
import badLogic.Mesh.PrimitiveType;
import badLogic.Texture.TextureFilter;
import badLogic.Texture.TextureWrap;



import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.text.Editable;
import android.text.method.KeyListener;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class Main extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		mGLView = new GLSurfaceView(this);
		mGLView.setRenderer(new AnaglyphRenderer(this));
		setContentView(mGLView);
	}

	@Override
	protected void onPause() {
		super.onPause();
		mGLView.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		mGLView.onResume();
	}

	private GLSurfaceView mGLView;
}

class AnaglyphRenderer extends GLSurfaceView implements Renderer, KeyListener {
	//private ParticleSystem mParticleSystem;
	private Square square= new Square();
	private Square sq2 = new Square(1);

	private Square flSquareRight = new Square();
	private Square flSquareLeft = new Square();
	private Camera camera = new Camera();
	float height;
	float width;
	float angle = 0;

	Mesh mesh;
	Mesh mesh2;
	Texture texture;
	boolean stereo = true;

	float lowBound = -0.8f;
	float highBound = 0.8f;
	float interocc = .2f;
	int switchCase = 1;
	

	@Override
	public void clearMetaKeyState(View view, Editable content, int states) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public int getInputType() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean onKeyDown(View view, Editable text, int keyCode,
			KeyEvent event) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onKeyOther(View view, Editable text, KeyEvent event) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onKeyUp(View view, Editable text, int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		return false;
	}


	public AnaglyphRenderer(Context ctx) {
		super(ctx);




	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glEnable(GL10.GL_POINT_SMOOTH);
		gl.glEnable(GL10.GL_LINE_SMOOTH);
		gl.glEnable(GL10.GL_POLYGON_SMOOTH_HINT);
		gl.glHint(GL10.GL_POLYGON_SMOOTH_HINT, GL10.GL_NICEST);

		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 


		mesh = MeshLoader.loadObj( gl, getResources().openRawResource(R.drawable.roboman2));
		mesh2 = MeshLoader.loadObj( gl, getResources().openRawResource(R.drawable.teapot));
		Bitmap bitmap = BitmapFactory.decodeStream( getResources().openRawResource(R.drawable.ship2) );
		texture = new Texture( gl, bitmap, TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge );
		bitmap.recycle();

		float[] lightColor = { 1, 1, 1, 1 };
		float[] ambientLightColor = {.2f, .2f, .2f, 1 };             
		gl.glLightfv( GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientLightColor, 0 );
		gl.glLightfv( GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightColor, 0 );
		gl.glLightfv( GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightColor, 0 );    

	}

	public void onSurfaceChanged(GL10 gl, int w, int h) {
		gl.glViewport(0, 0, w, h);
		width = w;
		height = h;
	}

	public void onDrawFrame(GL10 gl) {

		
		if(interocc > highBound || interocc < lowBound ){
			switchCase *=-1;
		}
		
		interocc += switchCase * 0.02f;
		
		
		gl.glEnable( GL10.GL_LIGHTING );
		gl.glEnable( GL10.GL_LIGHT0 );          
		float[] direction = { 1, 0.5f, 0, 0 };
		gl.glLightfv( GL10.GL_LIGHT0, GL10.GL_POSITION, direction, 0 );
		gl.glEnable( GL10.GL_COLOR_MATERIAL );
		if(stereo) {
			float near = 1f;
			float far = 10000f;
			float focalLength = 30.0f;
			float aperature = 55.0f;
			
			float aspect  = width / height;
			float halfap = (float) Math.toRadians(aperature/2);
			float adj     = (float) (near * Math.tan(halfap));


			gl.glMatrixMode(GL10.GL_PROJECTION);
			gl.glLoadIdentity();


			gl.glClearColor(0,0f,0f,1.0f);
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
			gl.glColorMask(false, false, true,false);
			
			
			//set camera for right eye
			float left  = (float) (-aspect * adj - interocc/2 * near/focalLength);
			float right =   (float) (aspect * adj - interocc/2 * near/focalLength);
			float top = adj;
			float bottom = - top;
			gl.glFrustumf(left, right, bottom, top, near, far);
			GLU.gluLookAt(gl, camera.x-interocc/2, camera.y, camera.z, camera.lookX-interocc/2, camera.lookY, camera.lookZ, 0.0f, 1.0f, 0f);


			//gl.glEnable( GL10.GL_TEXTURE_2D );
			//texture.bind();  
			//draw scene
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();
			gl.glTranslatef(-1.0f, 0.0f, 10f);
			gl.glRotatef( angle, 0, 1, 0 );

			//square.draw(gl);

			mesh.render( PrimitiveType.Lines );       

			gl.glPopMatrix();

			gl.glColor4f(1f,1f,1f,1f);

			//gl.glColorMask(true, true, true, false);
			gl.glPushMatrix();
			gl.glTranslatef(3.0f, 0.0f, 22f);
			//gl.glColor4f(0f, 0f, 0f, 1f);
			//flSquareLeft.draw(gl);
			mesh2.render(PrimitiveType.Lines);
			gl.glPopMatrix();

			gl.glColor4f(1f,1f,1f,1f);

			gl.glFlush();

			gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
			gl.glMatrixMode(GL10.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE);

			gl.glColorMask(true, false, false, false);
			//set camera for left eye
			left  = (float) (- aspect * adj + interocc/2 * near/focalLength);
			right =   (float) (aspect * adj + interocc/2 * near/focalLength);
			top    =   adj;
			bottom = - top;

			gl.glFrustumf(left, right, bottom, top, near, far);
			GLU.gluLookAt(gl, camera.x+interocc/2, camera.y, camera.z, camera.lookX+interocc/2, camera.lookY, camera.lookZ, 0.0f, 1.0f, 0f);

			//gl.glEnable( GL10.GL_TEXTURE_2D );
			//texture.bind();  
			//draw scene
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();
			gl.glTranslatef(-1.0f, 0.0f, 10f);
			gl.glRotatef( angle, 0, 1, 0 );
			//square.draw(gl);
			mesh.render( PrimitiveType.Lines );
			gl.glPopMatrix();

			gl.glPushMatrix();
			gl.glTranslatef(3.0f, 0.0f, 22f);
			mesh2.render(PrimitiveType.Lines);
			gl.glPopMatrix();


			gl.glFlush();
		}
		else
		{
			gl.glClearColor(0,0.5f,0f,1.0f);
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
			GLU.gluPerspective(gl, 45, 320/480, 1, 10000);
			GLU.gluLookAt(gl, camera.x, camera.y, camera.z, camera.lookX, camera.lookY, camera.lookZ, 0.0f, 1.0f, 0f);
			gl.glEnable( GL10.GL_TEXTURE_2D );
			texture.bind();  
			//draw scene
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();
			gl.glTranslatef(0.0f, 0.0f, 10f);
			gl.glRotatef( angle, 0, 1, 0 );
			mesh.render( PrimitiveType.Lines );
			gl.glPopMatrix();

		}
		angle+= .01 * 180;
		if( angle > 360 )
			angle = 0;


	}

	
}